package com.zhangzhan.gulimallware.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangzhan.gulimallcommcon.enums.ware.WareConstant;
import com.zhangzhan.gulimallcommcon.util.PageUtils;
import com.zhangzhan.gulimallcommcon.util.Query;
import com.zhangzhan.gulimallcommcon.util.R;
import com.zhangzhan.gulimallware.dao.PurchaseDao;
import com.zhangzhan.gulimallware.entity.PurchaseDetailEntity;
import com.zhangzhan.gulimallware.entity.PurchaseEntity;
import com.zhangzhan.gulimallware.entity.WareSkuEntity;
import com.zhangzhan.gulimallware.feign.ProductFeignService;
import com.zhangzhan.gulimallware.service.PurchaseDetailService;
import com.zhangzhan.gulimallware.service.PurchaseService;
import com.zhangzhan.gulimallware.service.WareSkuService;
import com.zhangzhan.gulimallware.vos.PurchaseDoneVo;
import com.zhangzhan.gulimallware.vos.PurchaseItemDoneVo;
import com.zhangzhan.gulimallware.vos.PurchaseMergeVo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Resource
    private PurchaseDetailService purchaseDetailService;

    @Resource
    private WareSkuService wareSkuService;

    @Resource
    private ProductFeignService productFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceiveList(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                Wrappers.<PurchaseEntity>lambdaQuery().eq(PurchaseEntity::getStatus, 0).or().eq(PurchaseEntity::getStatus, 1)
        );

        return new PageUtils(page);
    }

    /**
     * @param vo
     * @return void
     * @description 采购需求合并采购单
     * @author zhangyiheng
     * @date 2024/6/19 1:43
     */
    @Transactional
    @Override
    public void merge(PurchaseMergeVo vo) {
        Long purchaseId = vo.getPurchaseId();
        if (Objects.isNull(purchaseId)) {
            //创建新采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchaseEntity);

            purchaseId = purchaseEntity.getId();
        }

        PurchaseEntity purchase = this.getById(purchaseId);
        if (!Objects.isNull(purchase)) {
            if (purchase.getStatus() != WareConstant.PurchaseStatusEnum.CREATED.getCode() && purchase.getStatus() != WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                throw new RuntimeException("此采购单不是新建或分配状态");
            }
        }


        List<Long> items = vo.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = items.stream().map(po -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            purchaseDetailEntity.setId(po);
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());

            return purchaseDetailEntity;
        }).toList();


        purchaseDetailService.updateBatchById(purchaseDetailEntities);

        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setUpdateTime(new Date());
        this.update(purchaseEntity, Wrappers.<PurchaseEntity>lambdaUpdate()
                .eq(PurchaseEntity::getId, purchaseId));
    }

    @Transactional
    @Override
    public void received(List<Long> purchaseIds) {
        //修改采购单状态
        List<PurchaseEntity> purchaseEntities = purchaseIds.stream().map(this::getById)
                .filter(po -> {
                    //必须是已分配状态
                    return po.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode();
                }).map(po -> {
                    PurchaseEntity purchaseEntity = new PurchaseEntity();
                    purchaseEntity.setId(po.getId());
                    purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
                    purchaseEntity.setUpdateTime(new Date());
                    return purchaseEntity;
                }).toList();

        //修改采购需求状态
        if (CollUtil.isNotEmpty(purchaseEntities)) {
            this.updateBatchById(purchaseEntities);
            List<Long> purchaseIds2 = purchaseEntities.stream().map(PurchaseEntity::getId).toList();

            List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.list(Wrappers.<PurchaseDetailEntity>lambdaQuery().in(PurchaseDetailEntity::getPurchaseId, purchaseIds2));
            if (CollUtil.isEmpty(purchaseDetailEntities)) {
                log.error("当前采购单无分配任何采购需求！");
                throw new RuntimeException("领取失败，当前采购单无分配任何采购需求！");
            }

            purchaseDetailService.update(Wrappers.<PurchaseDetailEntity>lambdaUpdate()
                    .set(PurchaseDetailEntity::getStatus, WareConstant.PurchaseDetailStatusEnum.BUYING.getCode())
                    .in(PurchaseDetailEntity::getPurchaseId, purchaseIds2));

        } else {
            log.error("领取失败，请重试！:" + purchaseIds);
            throw new RuntimeException("领取失败，请重试！");
        }
    }

    @Transactional
    @Override
    public void done(PurchaseDoneVo vo) {


        //更新采购需求状态
        List<PurchaseItemDoneVo> purchaseDetailDone = vo.getItems();
        List<Long> purchaseDetailDoneIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(purchaseDetailDone)) {
            List<PurchaseDetailEntity> purchaseDetailEntities = new ArrayList<>();

            boolean rest = true;
            for (PurchaseItemDoneVo doneVo : purchaseDetailDone) {
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                if (Objects.equals(doneVo.getStatus(), WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode())) {
                    rest = false;
                }else {
                    purchaseDetailDoneIds.add(doneVo.getItemId());
                }
                purchaseDetailEntity.setId(doneVo.getItemId());
                purchaseDetailEntity.setStatus(doneVo.getStatus());
                purchaseDetailEntities.add(purchaseDetailEntity);

            }

            if (CollUtil.isNotEmpty(purchaseDetailEntities)) {
                purchaseDetailService.updateBatchById(purchaseDetailEntities);

                //更新采购单状态  根据采购需求状态来确定
                Long purchaseId = vo.getId();
                this.update(Wrappers.<PurchaseEntity>lambdaUpdate()
                        .set(PurchaseEntity::getStatus, rest ? WareConstant.PurchaseStatusEnum.FINISH.getCode() : WareConstant.PurchaseStatusEnum.HASERROR.getCode())
                        .set(PurchaseEntity::getUpdateTime, new Date())
                        .eq(PurchaseEntity::getId, purchaseId));


                //更新库存信息
                purchaseDetailDoneIds
                        .forEach(po -> {
                            PurchaseDetailEntity purchaseDetail = purchaseDetailService.getById(po);
                            WareSkuEntity wareSku = wareSkuService.getOne(Wrappers.<WareSkuEntity>lambdaQuery().eq(WareSkuEntity::getSkuId,purchaseDetail.getSkuId()));
                            String skuName = "";
                            try {
                                R r = productFeignService.getSkuName(purchaseDetail.getSkuId());
                                if (r.getCode() > 1) {
                                    log.error("远程调用获取skuName失败");
                                }
                                skuName = (String) r.get("data");
                            } catch (Exception e) {
                            }
                            if (Objects.isNull(wareSku)) {
                                wareSku = new WareSkuEntity();
                                wareSku.setSkuId(purchaseDetail.getSkuId());
                                wareSku.setStock(purchaseDetail.getSkuNum());
                                wareSku.setStockLocked(0);
                                wareSku.setSkuName(skuName);
                                wareSkuService.save(wareSku);
                            } else {
                                wareSku.setSkuName(skuName);
                                wareSku.setStock(wareSku.getStock() + purchaseDetail.getSkuNum());
                                wareSkuService.update(wareSku, Wrappers.<WareSkuEntity>lambdaUpdate()
                                        .eq(WareSkuEntity::getId, wareSku.getId()));
                            }
                        });
            }


        }


    }

}